﻿package com.bizmlib.utils
{
	import flash.display.DisplayObject;
	import flash.events.EventDispatcher;
	import flash.geom.Rectangle;
	
	
	public class ItemsArrangeManager extends EventDispatcher
	{
		public static const ORIENTATION_NONE:String = "none";
		public static const ORIENTATION_HORIZONTAL:String = "horizontal";
		public static const ORIENTATION_VERTICAL:String = "vertical";
		
		public var itemsList:Array;
		public var orientation:String;
		public var hSpacing:Number;
		public var vSpacing:Number;
		public var draggingItemIndex:Number;
		
		private var __zeroPointPosition:String;
		protected var isLeft:Boolean;
		protected var isHCenter:Boolean;
		protected var isRight:Boolean;
		protected var isTop:Boolean;
		protected var isVCenter:Boolean;
		protected var isBottom:Boolean;
		
		
		public function ItemsArrangeManager(orientation:String = undefined)
		{
			zeroPointPosition = "TL";
			this.orientation = orientation || ORIENTATION_HORIZONTAL;
			hSpacing = 0;
			vSpacing = 0;
		}
		
		
		public function set zeroPointPosition(value:String):void
		{
			__zeroPointPosition = value;
			updateZeroPoint();
		}
		public function get zeroPointPosition():String
		{
			return __zeroPointPosition;
		}
		
		
		public function calculatePositionIndex(x:Number, y:Number):Number
		{
			//trace(this + ".calculatePositionIndex(" + arguments + ")");
			
			var index:Number = undefined;
			
			switch(orientation)
			{
				case ORIENTATION_HORIZONTAL:
					index = calculatePositionIndexHorizontalImplementation(x, y);
					break;
				case ORIENTATION_VERTICAL:
					index = calculatePositionIndexVerticalImplementation(x, y);
					break;
			}
			
			return index;
		}
		protected function calculateItemBoundingRect(item:DisplayObject):Rectangle
		{
			var rect:Rectangle = new Rectangle(item.x - hSpacing/2, item.y - vSpacing/2, item.width + hSpacing, item.height + vSpacing);
			return rect;
		}
		protected function calculatePositionIndexHorizontalImplementation(x:Number, y:Number):Number
		{
			for(var i:Number=0; i<itemsList.length; i++)
			{
				var item:DisplayObject = itemsList[i] as DisplayObject;
				var boundRect:Rectangle = calculateItemBoundingRect(item);
				
				if(x>=boundRect.left && x<=boundRect.right && y>=boundRect.top && y<=boundRect.bottom)
				{
					if(x<(boundRect.x + boundRect.width/2))
					{
						return ((!isNaN(draggingItemIndex)) && draggingItemIndex<i) ? (i - 1) : i;
					}
					else
					{
						return ((!isNaN(draggingItemIndex)) && draggingItemIndex>i) ? (i + 1) : i;
					}
				}
			}
			
			return undefined;
		}
		protected function calculatePositionIndexVerticalImplementation(x:Number, y:Number):Number
		{
			for(var i:Number=0; i<itemsList.length; i++)
			{
				var item:DisplayObject = itemsList[i] as DisplayObject;
				var boundRect:Rectangle = calculateItemBoundingRect(item);
				
				if(x>=boundRect.left && x<=boundRect.right && y>=boundRect.top && y<=boundRect.bottom)
				{
					if(y<(boundRect.y + boundRect.height/2))
					{
						return (isNaN(draggingItemIndex) ? i : ((draggingItemIndex<i) ? (i - 1) : i));
						//return ((!isNaN(draggingItemIndex)) && draggingItemIndex<i) ? (i - 1) : i;
					}
					else
					{
						return (isNaN(draggingItemIndex) ? (i + 1) : ((draggingItemIndex>i) ? (i + 1) : i));
						//return ((!isNaN(draggingItemIndex)) && draggingItemIndex>i) ? (i + 1) : i;
					}
				}
			}
			
			return undefined;
		}
		
		
		protected function updateZeroPoint():void
		{
			isLeft = false;
			isHCenter = false;
			isRight = false;
			isTop = false;
			isVCenter = false;
			isBottom = false;
			
			if(zeroPointPosition && zeroPointPosition.length>0)
			{
				isLeft = (zeroPointPosition.substr(1, 1).toLowerCase() == "l");
				isHCenter = (zeroPointPosition.substr(1, 1).toLowerCase() == "m");
				isRight = (zeroPointPosition.substr(1, 1).toLowerCase() == "r");
				isTop = (zeroPointPosition.substr(0, 1).toLowerCase() == "t");
				isVCenter = (zeroPointPosition.substr(0, 1).toLowerCase() == "m");
				isBottom = (zeroPointPosition.substr(0, 1).toLowerCase() == "b");
			}
		}
		
		
		override public function toString():String
		{
			return "[ItemsArrangeManager	orientation:'" + orientation + "']";
		}
	}
}